# Пораждающий шаблон проектирования ("Абстрактаная фабрика")
# Предоставляет интерфейс для создания семейств взаимосвязаных или взаимозависимый объектов, не специфицируя их на конкретных классах
# Шаблон применяется в случаях когда программа должна быть не зависима от процессов и типов создаваемый новых объектов


import abc


class IEngine(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def realese_engine(self):
        pass


class JapaneseEngine(IEngine):
    def realese_engine(self):
        print("Японский двигатель")


class RussianEngine(IEngine):
    def realese_engine(self):
        print("Русский двигатель")


class ICar(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def realese_car(self, enginge: IEngine):
        pass


class JapaneseCar(ICar):
    def realese_car(self, enginge: IEngine):
        print("Собрали японский автомабиль, ", end="")
        enginge.realese_engine()


class RussianCar(ICar):
    def realese_car(self, enginge: IEngine):
        print("Собрали русский автомобиль, ", end="")
        enginge.realese_engine()


class IFactory(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def create_engine(self) -> IEngine:
        pass

    @abc.abstractmethod
    def create_car(self) -> ICar:
        pass


class JapaneseFactory(IFactory):
    def create_engine(self):
        return JapaneseEngine()

    def create_car(self):
        return JapaneseCar()


class RussianFactory(IFactory):
    def create_engine(self):
        return RussianEngine()

    def create_car(self):
        return RussianCar()


if __name__ == "__main__":
    j_factory = JapaneseFactory()
    j_engine = j_factory.create_engine()
    j_car = j_factory.create_car()
    j_car.realese_car(j_engine)
    # Собрали японский автомабиль, Японский двигатель

    ru_factory = RussianFactory()
    ru_engine = ru_factory.create_engine()
    ru_car = ru_factory.create_car()
    ru_car.realese_car(ru_engine)
    # Собрали русский автомобиль, Русский двигатель
